package com.chuangke.lowcode.component.handle;

import com.chuangke.common.exception.ChuangkeException;
import com.chuangke.lowcode.LowCodeContext;
import com.chuangke.lowcode.component.ProgressComponent;
import com.chuangke.lowcode.model.EntityModel;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据处理，将数据分模型组装
 */
@Component
@Transactional(rollbackFor = Throwable.class)
@SuppressWarnings({"rawtypes", "unchecked"})
public class BeforeSaveHandleDataComponent implements ProgressComponent {

    public void process(LowCodeContext modelContext) {
        Map<String, List> allModelDatas = new HashMap<>();
        buildData(modelContext.getEntityModel(), modelContext.getDatas(), allModelDatas);
        modelContext.setModelDatas(allModelDatas);
    }

    private List<Object> buildData(EntityModel model, List datas, Map<String, List> dataMap) {
        if (CollectionUtils.isEmpty(datas)) {
            return null;
        }

        List existDataList = dataMap.get(model.getId());
        if (CollectionUtils.isEmpty(existDataList)) {
            dataMap.put(model.getId(), datas);
        } else {
            existDataList.addAll(datas);
            dataMap.put(model.getId(), existDataList);
        }

        if (CollectionUtils.isEmpty(model.getChildren())) {
            return datas;
        }

        for (EntityModel childModel : model.getChildren()) {
            List dataList = new ArrayList<>();
            for (Object data : datas) {
                List modelData = getModelData(data, childModel);
                if (CollectionUtils.isEmpty(modelData)) {
                    continue;
                }
                dataList.addAll(buildData(childModel, modelData, dataMap));
            }
            dataMap.put(childModel.getId(), dataList);
        }
        return datas;
    }

    private List getModelData(Object parentModelData, EntityModel childModel) {
        Field[] fields = parentModelData.getClass().getDeclaredFields();

        List dataList = new ArrayList<>();
        for (Field f : fields) {
            if (f.getType() != List.class) {
                continue;
            }

            // 如果是List类型，得到其Generic的类型
            Type genericType = f.getGenericType();
            if (genericType == null) {
                continue;
            }

            // 如果是泛型参数的类型
            if (genericType instanceof ParameterizedType) {
            	ParameterizedType pt = (ParameterizedType)genericType ;
                // 得到泛型里的class类型对象
                Class genericClazz = (Class) pt.getActualTypeArguments()[0];
                if (genericClazz.equals(childModel.getEntityClass())) {
                    f.setAccessible(true);
                    try {
                       List fDatas = (List<Object>) f.get(parentModelData) ;
                       if(CollectionUtils.isNotEmpty(fDatas)){
                           dataList.addAll(fDatas);
                       }
                    } catch (Exception e) {
                        throw new ChuangkeException(e);
                    }
                }
            }
        }
        return dataList;
    }
}
